<?php
include_once $_SERVER['DOCUMENT_ROOT'].'/lib/Cache.php';

class Foursquare{
	private $api_key='client_id=ZM3ON3ZHY3TWMU4XYSCVDWYCYGMZVZQ23IBL5BSBN0J10VWS&client_secret=CJHGV2KMFICEJ5DMCLWIQG5UZ51ZFC0QH1KZ4L1EMQ1KTT1J&v=20130901&locale=ru';
	private $defCAts='4d4b7105d754a06378d81259'; //https://developer.foursquare.com/categorytree
	

	protected static $_instance;
	private function __construct(){}
	private function __clone(){}
	public static function inst(){
	  if( null===self::$_instance ){
	    self::$_instance=new self();
		}
		return self::$_instance;
	}

	protected $errors=array('err'=>array(),'wrn'=>array());
	protected function error($msg){ $this->errors['err'][]=$msg; return false;}
	protected function warning($msg){ $this->errors['wrn'][]=$msg; return false;}
	public function getError(){ return $this->errors['err'][ count($this->errors['err'])-1 ]; }
	public function getErrors(){ return $this->errors['err']; }
	public function getWarning(){ return $this->errors['wrn'][ count($this->errors['wrn'])-1 ]; }
	public function getWarnings(){ return $this->errors['wrn']; }

	/**************************
	 *	Произвольный запрос к API
	***************************/
	function request($fs_query,$headers=array()){
	  //Запрашиваю
		// Create a stream
		// File_get_content with headers http://stackoverflow.com/questions/2107759/php-file-get-contents-and-headers
		$context = stream_context_create(
			array(
			  'http'=>array(
			    'method'=>"GET",
			    'header'=> implode("\r\n",$headers) //"Accept-language: en\r\n"
			  )
			)
		);

	  $json=@file_get_contents('http://api.foursquare.com'.$fs_query, false, $context);

	  if(empty($json))	return $this->error('empty foursquare response');

	  $dt=json_decode($json);
	  $this->cur_json=$json;
		
		return $dt;
	}
	
	/**************************
	 *	Получение данных о заведении по fs_ID
	 *  https://api.foursquare.com/v2/venues/513262d5e4b0e80cdba8eb71?client_id=ZM3ON3ZHY3TWMU4XYSCVDWYCYGMZVZQ23IBL5BSBN0J10VWS&client_secret=CJHGV2KMFICEJ5DMCLWIQG5UZ51ZFC0QH1KZ4L1EMQ1KTT1J&v=20130901
	***************************/
	function venue($req){
	  //validation request
	  if( empty($req['id']) )	return $this->error('Venue ID expected');

    //make request
	  $fs_query='/v2/venues/'.$req['id'].'?'.$this->api_key;
	  
	  $headers=array();
	  if( !empty($req['lang']) ) {
			$fs_query.='&locale='.$req['lang'];
			$headers[]='Accept-Language: '.$req['lang'];
		}

		$dt=$this->request($fs_query,$headers);

		//validation response
	  if( empty($dt->response->venue) )return $this->error('Venue not found');

		return $dt;
	}

	/**
   * Makes request to google maps API to make geocode;
   * поиск заведений
   * https://api.foursquare.com/v2/venues/search?near=kiev&intent=browse&query=SOME_QUERY&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&v=20130901
   * https://api.foursquare.com/v2/venues/search?ll=50.430145,30.460953&intent=match&query=SOME_QUERY&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&v=20130901
   * 
   * find(array(lat=>'',lng=>'',query=>'',radius=>''));
   *
   * @name find
   * @author  John Bor <johncomua@gmail.com>
   * @param array @reg  array(location=>string, lat=>Latitude,lng=>Longitude,query=>string,radius=>int)
   */
	function find($req){
	  if( empty($req['query']) )	return $this->error( 'Query expected' );

		if( preg_match('~[а-яА-Я]~', $req['query']) )			$req['query']=urlencode($req['query']);
		if( !empty($req['lat']) && !empty($req['lng']) )	$req['ll']=$req['lat'].','.$req['lng'];
		elseif( !empty($req['location']) )
			if(preg_match('~[а-яА-Я]~', $req['location']))	$req['query']=urlencode($req['location']);
			
	  //make requert
	  $intent=(!empty($req['intent']))?$req['intent']:'match';
	  $fs_query='/v2/venues/search/?intent='.$intent.'&query='. $req['query'] .'&limit=50&'.$this->api_key;
	  
	  if( !empty($req['ll']) ) $fs_query.='&ll='.$req['ll'];
	  elseif( !empty($req['location']) ) $fs_query.='&near='.$req['location'];
	  $headers=array();
	  if( !empty($req['lang']) ) {
			$fs_query.='&locale='.$req['lang'];
			$headers[]='Accept-Language: '.$req['lang'];
		}

		$cats=(!empty($req['category']))?$req['category']:$this->defCAts;
		$fs_query.='categoryId='.$cats;

	  if($dt=Cache::inst()->get($fs_query) ) return $dt;

	  $dt=$this->request($fs_query,$headers);
//echo '<pre class="debug">'.print_r ( $dt ,true).'</pre>';
		//Validate response
	  if( empty($dt->response->venues) ){
	    return $this->error('Venues not found');
		}
		//echo '<pre class="debug">'.print_r ( $dt->response->venues[0] ,true).'</pre>';
		$result=$this->parseGeoDetails( $dt->response->venues[0]->location );

		//Запрос подробностей заведения
		//$item=$this->venue( array( 'id'=>$dt->response->venues[0]->id ) );
		//echo '<pre class="debug">'.print_r ( $item ,true).'</pre>';

		$result['name']=$dt->response->venues[0]->name;
    $result['url']=((!empty($dt->response->venues[0]->url)))?$dt->response->venues[0]->url:'';
    $result['dataProvider']='FS';
    $result['wideInfo']=$dt->response->venues[0];
		
		Cache::inst()->set($fs_query,$result,Cache::year);
	  return $result;
	}
	
	function parseGeoDetails($result){
		//Формализую результат
		$geoDetail=array(
		  'countryIso'=>false,
		  'country'=>false,
		  'region'=>false,
		  'city'=>false,
		  'urbanarea'=>false,
		  'street'=>false,
		  'crossStreet'=>false,
		  'number'=>false,
		  'lat'=>false,
		  'lng'=>false,
		  'formatedAddr'=>false,
		  'geometry'=>false,
		);
		
		$geoDetail['lat']=$result->lat;
		$geoDetail['lng']=$result->lng;
		$geoDetail['formatedAddr']=implode(',', $result->formattedAddress);
		$geoDetail['countryIso']=$result->cc;
		$geoDetail['country']=$result->country;
		$geoDetail['region']=$result->state;
		$geoDetail['city']=$result->city;
		$geoDetail['street']=(!empty($result->crossStreet))?$result->crossStreet:$result->address;
		
		$t=explode(',', $result->address);
		if(count($t)==2)	$geoDetail['number']=$t[1];
		unset($t);
		
		if(empty($geoDetail['urbanarea']))$geoDetail['urbanarea']=$geoDetail['city'];
	  return $geoDetail;
	}
}
?>
